#!/bin/bash

. $ZMICRO_HOME/commands/machine/veth/config

is_namepsace_created() {
  sudo ip netns ls | grep $NETWORK_NAMESPACE >>/dev/null 2>&1
  if [ "$?" = "0" ]; then
    echo "true"
    return
  fi

  echo "false"
}

create_namespace() {
  # 1. Create Namespace
  sudo ip netns ls | grep $NETWORK_NAMESPACE >>/dev/null 2>&1
  if [ "$?" != "0" ]; then
    sudo ip netns add $NETWORK_NAMESPACE
  fi

  # 2. 设置网关
  # sudo ip netns exec ${NETWORK_NAMESPACE} ip route add default via $NETWORK_GATEWAY
}

create_bridge() {
  sudo ip link add ${NETWORK_BRIDGE} type bridge
  sudo ip addr add ${NETWORK_GATEWAY}/24 dev ${NETWORK_BRIDGE}
  sudo ip link set dev ${NETWORK_BRIDGE} up

  # 允许流量转发
  sudo iptables -L FORWARD -v | grep ${NETWORK_BRIDGE} >>/dev/null 2>&1
  if [ "$?" != "0" ]; then
    sudo iptables -A FORWARD -o ${NETWORK_BRIDGE} -j ACCEPT
    sudo iptables -A FORWARD -i ${NETWORK_BRIDGE} -j ACCEPT

    # @TODO
    sudo iptables -t nat -A POSTROUTING -s ${NETWORK_MASK} -j MASQUERADE
  fi
}

create_veth() {
  local veth_name=$1
  local veth_ip=$2
  local veth_name_inner=${veth_name}-0
  local veth_name_outer=${veth_name}-1

  sudo ip link show ${veth_name_outer} >>/dev/null 2>&1
  if [ "$?" = "0" ]; then
    log::success "veth ${veth_name} already exist."
    exit 0
  fi

  # 2. Create Veth
  sudo ip link add ${veth_name_inner} type veth peer name ${veth_name_outer}
  # 3. Join Namespace
  sudo ip link set ${veth_name_inner} netns $NETWORK_NAMESPACE

  # 4. Assign IP
  sudo ip netns exec $NETWORK_NAMESPACE ip addr add ${veth_ip}/24 dev ${veth_name_inner}
  sudo ip netns exec $NETWORK_NAMESPACE ip link set dev ${veth_name_inner} up

  #
  sudo ip link set ${veth_name_outer} master ${NETWORK_BRIDGE}
  sudo ip link set dev ${veth_name_outer} up

  # 添加默认网关
  sudo ip netns exec $NETWORK_NAMESPACE ip route list | grep "default via" >>/dev/null 2>&1
  if [ "$?" != "0" ]; then
    sudo ip netns exec ${NETWORK_NAMESPACE} ip route add default via $NETWORK_GATEWAY
  fi

  log::success "veth ${veth_name} created."
}

create() {
  local network_name=$1
  local network_ip=$2

  if [ "$(is_namepsace_created)" = "false" ]; then
    create_bridge
    create_namespace
  fi

  log::info "create network(${network_name}): ${network_ip}"

  # #
  create_veth $network_name $network_ip
}

help() {
  echo "Usage:"
  echo "  zmachine veth create <ip>"
  echo ""
}

core() {
  if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
    help
    exit 0
  fi

  local network_ip=$1
  if [ "$network_ip" = "" ]; then
    log::error "ip is required"
    exit 1
  fi

  # local network_name="zmicro_$(string::replace $network_ip .)"
  local last=$(string::split_last_element . $network_ip)
  local last_second=$(string::split_last_second_element . $network_ip)
  local network_name="zmicro_${last_second}${last}"

  create $network_name $network_ip
}

run() {
  core $@
}

run $@
